#!/bin/bash

# ==========================================
# 变量定义
# ==========================================
ROOT_DIR="demo_project"
ISO_ROOT="$ROOT_DIR/iso_root"
SCRIPTS_DIR="$ISO_ROOT/scripts"
CONFIG_DIR="$ISO_ROOT/configs"

# 清理旧环境
rm -rf "$ROOT_DIR"
mkdir -p "$SCRIPTS_DIR"
mkdir -p "$CONFIG_DIR"

echo "=== 开始构建项目目录结构 ==="

# ==========================================
# 1. 创建公共函数库 (scripts/common_lib.sh)
#    修改点：动态查找 configs 目录下唯一的 .json 文件
# ==========================================
cat > "$SCRIPTS_DIR/common_lib.sh" << 'EOF'
#!/bin/bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_err()  { echo -e "${RED}[ERR ]${NC} $1"; }

# 获取配置文件的路径
# 逻辑：
# 1. 如果传入了参数且文件存在，使用参数指定的文件。
# 2. 否则，自动查找 ../configs/ 目录下唯一的 *.json 文件。
get_config_file() {
    local input=$1
    local config_dir="$SCRIPT_HOME/../configs"
    
    # 1. 优先使用传入参数
    if [ -n "$input" ] && [ -f "$input" ]; then
        echo "$input"
        return
    fi
    
    # 2. 自动查找 configs 目录下唯一的 json 文件
    # find 查找 maxdepth 1，即只在 configs 当前层级查找
    local auto_conf=$(find "$config_dir" -maxdepth 1 -name "*.json" | head -n 1)

    if [ -n "$auto_conf" ]; then
        echo "$auto_conf"
    else
        # 找不到时的兜底（虽然逻辑上应该存在）
        echo "$config_dir/ztzh_config_iso.json"
    fi
}

# 执行单个模块的特定脚本
# 参数: 1=ConfigFile 2=ModuleName 3=ScriptType(install/uninstall/run/check_vers)
exec_module_script() {
    local config_file=$1
    local module_name=$2
    local script_type=$3
    local script_name="${script_type}.sh"

    # 从JSON中提取该模块的配置
    local module_json=$(jq -c ".modules[] | select(.name == \"$module_name\")" "$config_file")
    
    if [ -z "$module_json" ]; then
        return 0 # 模块未找到，跳过
    fi

    # 提取激活的版本
    local active_ver=$(echo "$module_json" | jq -r '.active_version // empty')
    local active_sub=$(echo "$module_json" | jq -r '.active_sub_version // empty')

    # 如果没有激活版本，跳过
    if [ -z "$active_ver" ] || [ "$active_ver" == "null" ]; then
        log_info "模块 [$module_name] 未配置激活版本，跳过。"
        return 0
    fi

    # 构建脚本路径: iso_root/模块名/版本号/脚本.sh
    # 注意：脚本是相对于执行路径的，我们需要定位到绝对路径或相对正确的路径
    # 假设调用者都在 scripts 目录下运行
    local module_path="$SCRIPT_HOME/../$module_name/$active_ver"
    local target_script="$module_path/$script_name"

    log_info "正在处理模块: $module_name | 版本: $active_ver | 子版本: $active_sub | 动作: $script_type"

    if [ -f "$target_script" ]; then
        # 切换到脚本所在目录执行，确保脚本内部相对路径正确
        pushd "$module_path" > /dev/null
        
        # 执行脚本，并将当前模块的完整json配置作为参数传入
        ./$script_name "$module_json"
        local ret=$?
        
        popd > /dev/null
        
        if [ $ret -ne 0 ]; then
            log_err "模块 [$module_name] 执行 $script_name 失败 (Code: $ret)"
            return 1
        else
            log_info "模块 [$module_name] 执行 $script_name 成功"
            return 0
        fi
    else
        # 脚本不存在默认视为成功
        log_warn "脚本不存在: $target_script (默认跳过)"
        return 0
    fi
}
EOF

# ==========================================
# 2. 生成 System 脚本
# ==========================================

# --- system_json_update.sh ---
# 扫描所有目录下的 ztzh_module.json 并汇总
# 修改点：生成任意名称的 json 文件，并清理旧文件
cat > "$SCRIPTS_DIR/system_json_update.sh" << 'EOF'
#!/bin/bash
SCRIPT_HOME=$(cd "$(dirname "$0")"; pwd)
source "$SCRIPT_HOME/common_lib.sh"

CONFIG_DIR="$SCRIPT_HOME/../configs"
ISO_ROOT="$SCRIPT_HOME/../"

# 定义本次生成的配置文件名称（演示文件名不固定）
OUTPUT_FILE_NAME="global_iso_config.json"
OUTPUT_FILE="$CONFIG_DIR/$OUTPUT_FILE_NAME"

log_info "准备生成汇总配置..."

# 1. 确保 configs 目录下有且仅有一个 json 文件，先清理旧的
rm -f "$CONFIG_DIR"/*.json

# 初始化JSON结构
echo '{"modules": []}' > "$OUTPUT_FILE"

# 查找所有 ztzh_module.json (排除 configs 目录本身，防止递归)
find "$ISO_ROOT" -name "ztzh_module.json" -not -path "*/configs/*" | while read json_file; do
    log_info "发现模块配置: $json_file"
    # 读取内容
    content=$(cat "$json_file")
    
    # 使用 jq 将新内容追加到 modules 数组中
    # 使用临时文件防止读写冲突
    jq --argjson new "$content" '.modules += [$new]' "$OUTPUT_FILE" > "${OUTPUT_FILE}.tmp" && mv "${OUTPUT_FILE}.tmp" "$OUTPUT_FILE"
done

log_info "汇总完成，配置文件路径: $OUTPUT_FILE"
# 格式化输出
jq '.' "$OUTPUT_FILE" > "${OUTPUT_FILE}.tmp" && mv "${OUTPUT_FILE}.tmp" "$OUTPUT_FILE"
EOF

# --- system_info.sh ---
# 展示版本树和激活状态
cat > "$SCRIPTS_DIR/system_info.sh" << 'EOF'
#!/bin/bash
SCRIPT_HOME=$(cd "$(dirname "$0")"; pwd)
source "$SCRIPT_HOME/common_lib.sh"

# 调用 common_lib 中的动态获取函数
CONFIG_FILE=$(get_config_file "$1")

if [ ! -f "$CONFIG_FILE" ]; then
    log_err "配置文件未找到 (configs目录下无json文件 或 指定文件不存在)"
    exit 1
fi

log_info "正在读取配置文件: $CONFIG_FILE"

echo "========================================"
echo "          系统模块版本状态表            "
echo "========================================"

# 获取模块数量
count=$(jq '.modules | length' "$CONFIG_FILE")

for ((i=0; i<$count; i++)); do
    name=$(jq -r ".modules[$i].name" "$CONFIG_FILE")
    desc=$(jq -r ".modules[$i].description" "$CONFIG_FILE")
    active_v=$(jq -r ".modules[$i].active_version" "$CONFIG_FILE")
    active_s=$(jq -r ".modules[$i].active_sub_version" "$CONFIG_FILE")

    echo -e "模块: ${GREEN}$name${NC} ($desc)"
    echo -e "  当前激活: Version=[${YELLOW}$active_v${NC}] SubVersion=[${YELLOW}$active_s${NC}]"
    echo "  可用版本树:"
    
    # 遍历该模块的所有版本
    jq -c ".modules[$i].versions[]" "$CONFIG_FILE" | while read ver_obj; do
        v_name=$(echo "$ver_obj" | jq -r '.version')
        
        marker=" "
        if [ "$v_name" == "$active_v" ]; then marker="*"; fi
        
        echo -e "    [$marker] 版本: $v_name"
        
        # 遍历子版本
        echo "$ver_obj" | jq -r '.sub_versions[]' | while read sub; do
            s_marker=" "
            # 只有当父版本也匹配时，子版本匹配才有意义
            if [ "$v_name" == "$active_v" ] && [ "$sub" == "$active_s" ]; then s_marker="*"; fi
            echo "        - [$s_marker] $sub"
        done
    done
    echo "----------------------------------------"
done
EOF

# --- system_executor_template (模板) ---
# 用于生成 install/uninstall/run/check_vers
create_executor() {
    local type=$1
    local filename="system_${type}.sh"
    
    cat > "$SCRIPTS_DIR/$filename" << EOF
#!/bin/bash
SCRIPT_HOME=\$(cd "\$(dirname "\$0")"; pwd)
source "\$SCRIPT_HOME/common_lib.sh"

# 动态查找配置文件
CONFIG_FILE=\$(get_config_file "\$1")
ACTION="$type"

log_info "=== 开始执行系统任务: \${ACTION^^} ==="
log_info "使用配置文件: \$CONFIG_FILE"

if [ ! -f "\$CONFIG_FILE" ]; then
    log_err "配置文件未找到"
    exit 1
fi

# 获取所有模块名称
modules=\$(jq -r '.modules[].name' "\$CONFIG_FILE")

has_error=0

for mod in \$modules; do
    if ! exec_module_script "\$CONFIG_FILE" "\$mod" "\$ACTION"; then
        has_error=1
    fi
done

if [ \$has_error -eq 0 ]; then
    log_info "=== 系统任务 \${ACTION^^} 全部完成 ==="
else
    log_err "=== 系统任务 \${ACTION^^} 完成，但存在错误，请检查日志 ==="
fi
EOF
}

create_executor "install"
create_executor "uninstall"
create_executor "run"
create_executor "check_vers"


# --- system_iso.sh ---
# 打包脚本
cat > "$SCRIPTS_DIR/system_iso.sh" << 'EOF'
#!/bin/bash
SCRIPT_HOME=$(cd "$(dirname "$0")"; pwd)
ISO_ROOT="$SCRIPT_HOME/../"
OUTPUT_ISO="$SCRIPT_HOME/../../output.iso"

echo "1. 更新汇总配置 json..."
bash "$SCRIPT_HOME/system_json_update.sh"

echo "2. 确保所有脚本具有执行权限..."
# 在制作ISO前必须赋权，ISO挂载后是只读的
chmod -R +x "$ISO_ROOT"

echo "3. 开始打包 ISO..."
# 使用 genisoimage 或 mkisofs
if command -v genisoimage >/dev/null 2>&1; then
    TOOL="genisoimage"
else
    TOOL="mkisofs"
fi

$TOOL -R -J -o "$OUTPUT_ISO" "$ISO_ROOT"

echo "ISO 生成完毕: $OUTPUT_ISO"
EOF


# ==========================================
# 3. 生成测试用例 (模块生成器)
# ==========================================

# 通用的模块脚本生成函数
# $1=模块路径 $2=版本号
generate_module_scripts() {
    local ver_path=$1
    local ver=$2
    
    for script in install uninstall run check_vers; do
        cat > "$ver_path/$script.sh" << EOF
#!/bin/bash
# 接收参数 JSON
MODULE_JSON=\$1

# 打印收到的信息
echo "  [Module-Script] ($script.sh) 正在运行..."
echo "  [Module-Script] 路径: \$(pwd)"
# 为了演示整洁，这里只打印参数长度或部分信息，实际开发可打印全部
# echo "  [Module-Script] 接收到的参数: \$MODULE_JSON"

# 模拟一些特定逻辑
if [ "$script" == "check_vers" ]; then
   echo "  [Module-Script] 正在检查版本 $ver ..."
   # 模拟偶尔检查成功
   exit 0
elif [ "$script" == "run" ]; then
   echo "  [Module-Script] 正在启动业务逻辑..."
   # 读取 active_sub_version 并寻找对应目录
   SUB_VER=\$(echo "\$MODULE_JSON" | jq -r '.active_sub_version')
   
   # 检查子版本目录是否存在
   if [ -d "\$SUB_VER" ]; then
       echo "  [Module-Script] 加载内核/编译器模块: \$SUB_VER"
       echo "  [Module-Script] 读取文件: ./\$SUB_VER/data.bin (模拟)"
   else
       echo "  [Module-Script] 错误: 子版本目录 \$SUB_VER 不存在"
       exit 1
   fi
fi
EOF
    done
}

# --- 模块 A: 驱动 (Driver_Net) ---
# 包含 2个版本，每个版本不同内核
mkdir -p "$ISO_ROOT/driver_net"

# version 1.0.0
mkdir -p "$ISO_ROOT/driver_net/1.0.0/5.10-kylin"
mkdir -p "$ISO_ROOT/driver_net/1.0.0/5.12-kylin"
touch "$ISO_ROOT/driver_net/1.0.0/5.10-kylin/data.bin"
generate_module_scripts "$ISO_ROOT/driver_net/1.0.0" "1.0.0"

# version 2.0.0
mkdir -p "$ISO_ROOT/driver_net/2.0.0/5.15-kylin"
generate_module_scripts "$ISO_ROOT/driver_net/2.0.0" "2.0.0"

# driver_net json
cat > "$ISO_ROOT/driver_net/ztzh_module.json" << EOF
{
  "name": "driver_net",
  "description": "高性能网络驱动",
  "versions": [
    { "version": "1.0.0", "sub_versions": ["5.10-kylin", "5.12-kylin"] },
    { "version": "2.0.0", "sub_versions": ["5.15-kylin"] }
  ],
  "active_version": "1.0.0",
  "active_sub_version": "5.10-kylin"
}
EOF

# --- 模块 B: 软件 (App_UI) ---
# 包含 1个版本，gcc区别
mkdir -p "$ISO_ROOT/app_ui"

# version 3.5.2
mkdir -p "$ISO_ROOT/app_ui/3.5.2/gcc-7.3"
mkdir -p "$ISO_ROOT/app_ui/3.5.2/gcc-9.0"
touch "$ISO_ROOT/app_ui/3.5.2/gcc-7.3/ui_bin"
generate_module_scripts "$ISO_ROOT/app_ui/3.5.2" "3.5.2"

# app_ui json
cat > "$ISO_ROOT/app_ui/ztzh_module.json" << EOF
{
  "name": "app_ui",
  "description": "用户图形界面",
  "versions": [
    { "version": "3.5.2", "sub_versions": ["gcc-7.3", "gcc-9.0"] }
  ],
  "active_version": "3.5.2",
  "active_sub_version": "gcc-7.3"
}
EOF

# --- 模块 C: 固件 (Firmware_X) ---
# 测试无配置激活版本的情况
mkdir -p "$ISO_ROOT/firmware_x"
mkdir -p "$ISO_ROOT/firmware_x/0.9/base"
generate_module_scripts "$ISO_ROOT/firmware_x/0.9" "0.9"

cat > "$ISO_ROOT/firmware_x/ztzh_module.json" << EOF
{
  "name": "firmware_x",
  "description": "底层固件",
  "versions": [
    { "version": "0.9", "sub_versions": ["base"] }
  ],
  "active_version": null,
  "active_sub_version": null
}
EOF

# ==========================================
# 4. 权限设置与完成
# ==========================================

chmod -R +x "$SCRIPTS_DIR"
echo "=== 目录结构和测试脚本生成完毕 ==="
echo "位置: $ISO_ROOT"

# 生成一个方便的测试运行脚本
cat > "$ROOT_DIR/run_test.sh" << 'EOF'
#!/bin/bash
ROOT_DIR=$(cd "$(dirname "$0")"; pwd)
SCRIPTS="$ROOT_DIR/iso_root/scripts"

echo ">>> 1. 更新 JSON 配置 (将自动生成 configs/global_iso_config.json)..."
$SCRIPTS/system_json_update.sh

echo ">>> 2. 查看当前系统信息 (System Info) - 测试自动查找配置文件..."
$SCRIPTS/system_info.sh

echo ">>> 3. 模拟系统安装 (System Install)..."
$SCRIPTS/system_install.sh

echo ">>> 4. 模拟系统运行 (System Run)..."
$SCRIPTS/system_run.sh

echo ">>> 5. 模拟检查版本 (Check Vers)..."
$SCRIPTS/system_check_vers.sh

echo ">>> 6. 打包 ISO..."
$SCRIPTS/system_iso.sh
EOF

chmod +x "$ROOT_DIR/run_test.sh"

echo "您可以运行: $ROOT_DIR/run_test.sh 开始验证。"
